import { Component, useState } from "react";
import { View, Text } from '@tarojs/components';
import { Body } from "../../componets/public/index";
import './2048.scss'

const Locn = () => [
  [0, 0, 0, 0],
  [0, 0, 0, 0],
  [0, 0, 0, 0],
  [0, 0, 0, 0]
];
type LocnType = Array<number[]>;
interface coordinateType {
  ['x']: number,
  x: number,
  y: number,
};
const ScoreItem = function(props) {
  const value = props.value;
  const  colorList = ["wheat","#DA70D6","#BA55D3","#E6E6FA","#87CEFA","#7FFFAA","#FAFAD2","#F0E68C","#FFDAB9","#BC8F8F","#4169E1","#FFE4E1"];
  const  scoreValue = [0,2,4,8,16,32,64,128,256,512,1024,2048];
  let colorValue = colorList[0];
  scoreValue.some((item, index)=> {
    if (value === item) {
      colorValue = colorList[index];
    }
    return value === item ;
  });
  return <View className="score-item" style={{backgroundColor: colorValue}}>{value}</View>
}
const GameBox = function(props) {
  return (
    <View className="game-box">{props.children}</View>
  )
}
const ScoreShow = function({score}) {
  return (
    <View className="score-box">
      <Text>当前得分：</Text><Text>{score}</Text>
    </View>
  )
}
const GameEndPopup  = function ({value, reset}) {
  return (<View className="popup">
    <View className="result">得分：{value}</View>
    <View className="but" onClick={reset}>重新开始</View>
  </View>)
}
const ContentBody = function() {
  const locnArr = Locn();
  Init(locnArr);
  const [locnMap, setLocnMap ] = useState(locnArr);
  const [score, serScore] = useState(0);
  const [isGame, setIsGame] = useState(true);
  const moveTop = () => {
    const tempPlan: Array<coordinateType> = [];
    const newLocnMap = JSON.parse(JSON.stringify(locnMap));
    let scoreValue = 0;
    for(let y = newLocnMap.length - 1; y >= 0; y -= 1) {
      const row = newLocnMap[y];
      for(let x = 0; x < row.length; x += 1) {
        for(let cx = 0; cx < row.length; cx += 1) {
          if (y - 1 >= 0 && newLocnMap[y - 1][cx] === row[cx]) {
            newLocnMap[y - 1][cx] += row[cx];
            newLocnMap[y][cx] = 0;
          }
          if ( y - 1 >= 0 && newLocnMap[y - 1][cx] === 0) {
            newLocnMap[y - 1][cx] = row[cx];
            newLocnMap[y][cx] = 0;
          }
        }
        if (row[x] === 0) {
          tempPlan.push({x, y});
        }
        if (row[x] !== 0) {
          scoreValue += row[x];
        }
      }
    }
    const randomLocnMap = random(newLocnMap, tempPlan);
    serScore(scoreValue);
    setLocnMap(randomLocnMap);
    judgment(randomLocnMap);
  }
  const moveBottom = () => {
    const tempPlan: Array<coordinateType> = [];
    const newLocnMap = JSON.parse(JSON.stringify(locnMap));
    let scoreValue = 0;
    newLocnMap.forEach((row: number[], y: number) => {
      row.forEach(() => {
        row.forEach((_, x) => {
          const len = y + 1 >= newLocnMap.length ? newLocnMap.length - 1 : y + 1;
          if (y <newLocnMap.length - 1 && newLocnMap[len][x] === 0) {
            newLocnMap[len][x] = newLocnMap[y][x];
            newLocnMap[y][x] = 0;
          };
          if (y <newLocnMap.length - 1 && newLocnMap[len][x] === newLocnMap[y][x]) {
            newLocnMap[len][x] += newLocnMap[y][x];
            newLocnMap[y][x] = 0;
          }
        });
      })
      row.forEach((val, x) => {
        if (val === 0) {
          const coordinate: {x: number, y: number} = {x, y}
          tempPlan.push(coordinate)
        }
        if (val !== 0) {
          scoreValue += val;
        }
      })
    });
    const randomLocnMap = random(newLocnMap, tempPlan);
    serScore(scoreValue);
    setLocnMap(randomLocnMap);
    judgment(randomLocnMap);
  }
  const moveLeft = () => {
    const tempPlan: Array<coordinateType> = [];
    const newLocnMap = JSON.parse(JSON.stringify(locnMap));
    let scoreValue = 0;
    newLocnMap.forEach((row: number[], y: number) => {
      row.reverse();
      row.forEach(() => {
        row.forEach((val, x) => {
          if (row[x + 1] === val) {
            row[x + 1] += val;
            row[x] = 0;
          };
          if (row[x + 1] === 0) {
            row[x + 1] = val;
            row[x] = 0;
          }
        });
      })
      row.reverse();
      row.forEach((val, x) => {
        if (val === 0) {
          const coordinate: {x: number, y: number} = {x, y}
          tempPlan.push(coordinate)
        }
        if (val !== 0) {
          scoreValue += val;
        }
      })
    });
    const randomLocnMap = random(newLocnMap, tempPlan);
    serScore(scoreValue);
    setLocnMap(randomLocnMap);
    judgment(randomLocnMap);
  }
  const moveRight = async () => {
    const tempPlan: Array<coordinateType> = [];
    const newLocnMap = JSON.parse(JSON.stringify(locnMap));
    let scoreValue = 0;
    newLocnMap.forEach((row: number[], y: number) => {
      row.forEach(() => {
        row.forEach((val, x) => {
          if (row[x + 1] === val) {
            row[x + 1] += val;
            row[x] = 0;
          };
          if (row[x + 1] === 0) {
            row[x + 1] = val;
            row[x] = 0;
          }
        });
      })
      row.forEach((val, x) => {
        if (val === 0) {
          const coordinate: {x: number, y: number} = {x, y}
          tempPlan.push(coordinate)
        }
        if (val !== 0) {
          scoreValue += val;
        }
      })
    });
    const randomLocnMap = random(newLocnMap, tempPlan);
    serScore(scoreValue);
    setLocnMap(randomLocnMap);
    judgment(randomLocnMap);
  }
  function random(locnMap: LocnType, tempPlan: Array<coordinateType>): LocnType {
    if (tempPlan.length === 0) {
      return locnMap;
    };
    const randomVal = Math.floor(Math.random() * tempPlan.length);
    const { x, y } = tempPlan[randomVal];
    const randomArr = [2, 4, 8, 16];
    locnMap[y][x] = randomArr[Math.floor(Math.random() * randomArr.length)];
    return locnMap;
  };
  function Init(locnArr) {
    const lenY = locnArr.length;
    const lenX = locnArr[0].length;
    const randomArr = [2, 4, 8, 16];
    locnArr[Math.floor(Math.random() * lenY)][Math.floor(Math.random() * lenX)] = randomArr[Math.floor(Math.random() * randomArr.length)];
  }
  function endGame() {
    setIsGame(false);
  }
  function startGame() {
    const locnArr = Locn();
    Init(locnArr);
    setLocnMap(locnArr);
    serScore(0);
    setIsGame(true);
  }
  function judgment(randomLocnMap: number[][]) {
    let isCoca = false;
    let columnControl = true;
    const tempPlan: number[] = [];
    randomLocnMap.forEach((row: number[], y: number)=> {
      const rowTemp: number[] = [];
      row.forEach((value: number, x: number) => {
        if (value !== 0) {
          rowTemp.push(value);
        };
        if (value === 0) {
          tempPlan.push(0);
        }
        if (columnControl) {
          const columnTemp: number[] = [];
          const columnLen = randomLocnMap.length;
          for(let i = 0; i < columnLen; i += 1) {
            const columnVal = randomLocnMap[i][x];
            if (columnVal !== 0) {
              columnTemp.push(columnVal);
            }
          }
          columnTemp.forEach((val, index) => {
            if (val === columnTemp[index + 1]) {
              isCoca = true;
            }
          });
        }
      });
      rowTemp.forEach((val, index)=> {
        if(val === rowTemp[index + 1]) {
          isCoca = true;
        }
      });
      columnControl = false;
    });
    // 达成条件： 1，所有坑都填满了。 2， 同一路径上所有值不可加。
    if (!isCoca && tempPlan.length === 0) {
      endGame();
    }
  }
  return (
    <Body
      moveBottom={moveBottom}
      moveLeft={moveLeft}
      moveTop={moveTop}
      moveRight={moveRight}
      isMove={isGame}
      className='gr-bg__red_walls'
      navText='2048'
    >
      <ScoreShow score={score}></ScoreShow>
      <GameBox>
        {locnMap.map((item) => {
          return item.map((val)=> {
            return <ScoreItem value={val}></ScoreItem>
          })
        })}
      </GameBox>
      {isGame ? <View></View> : <GameEndPopup value={score} reset={startGame}></GameEndPopup>}
    </Body>
  )
}

export default class Index extends Component {
  constructor(props){
    super(props);
  }
  componentDidMount () { }
  componentWillUnmount () { }
  componentDidShow () { }
  componentDidHide () { }
  onShareAppMessage (share) {
    if (share.from === 'button') {
      // 来自页面内转发按钮
      console.log(share.target)
    }
    return {
      title: '一起来看看',
      path: '/pages/2048/2048'
    }
  }
  render () {
    return (
      <ContentBody></ContentBody>
    )
  }
}

